﻿using System;
using System.Collections.Generic;
using System.Globalization;

namespace FBProject.BusinessLogic.MSProjectProxies
{
    public class MSTaskProxy
    {
        private MSProjectProxy MSProjectProxy { get; set; }
        private Microsoft.Office.Interop.MSProject.Task MSTask { get; set; }

        public int Id
        {
            get { return this.MSTask.ID; }
        }

        public string TaskNumber
        {
            get { return this.MSTask.Text1; }
            set { this.MSTask.Text1 = value; }
        }

        public string TaskNumberFormatted
        {
            get 
            {
                if (string.IsNullOrEmpty(this.TaskNumber))
                {
                    return string.Empty;
                }
                else
                {
                    return string.Format(MSProjectProxy.FBCaseNumberFormat, this.TaskNumber);
                }
            }
        }

        public string TaskHyperlink
        {
            get 
            {
                if (!string.IsNullOrEmpty(this.TaskNumber))
                {
                    var fbUrl = MSProjectProxy.FBUrl;
                    if (!string.IsNullOrEmpty(fbUrl))
                    {
                        if (!fbUrl.EndsWith("/"))
                        {
                            fbUrl += "/";
                        }
                        return string.Format(MSProjectProxy.FBCaseUrlFormat, fbUrl, this.TaskNumber);
                    }
                }
                return string.Empty; 
            }
        }

        public string Name
        {
            get { return this.MSTask.Name; }
        }

        public double Work
        {
            get { return (double)this.MSTask.Work; }
            set { this.MSTask.Work = value; }
        }

        public double Estimate
        {
            get { return this.MSTask.Number1 * 60; }
            set { this.MSTask.Number1 = value / 60.0; }
        }

        public double RemainingWork
        {
            get { return (double)this.MSTask.RemainingWork; }
            set { this.MSTask.RemainingWork = value; }
        }

        public Microsoft.Office.Interop.MSProject.Resources Resources
        {
            get { return this.MSTask.Resources; }
        }

        public string Resource
        {
            get 
            {
                return this.Resources.Count > 0 ? this.Resources[1].Name : string.Empty;
            }
            set 
            {
                this.MSTask.ResourceNames = value;
            }
        }

        public short Priority
        {
            get { return (short)this.MSTask.Priority; }
            set { this.MSTask.Priority = value; }
        }

        public string Milestone
        {
            get { return this.MSTask.Text2; }
            set { this.MSTask.Text2 = value; }
        }

        public bool Completed
        {
            get { return (short)this.MSTask.PercentWorkComplete >= 100; }
        }

        public bool InProgress
        {
            get { return ((short)this.MSTask.PercentWorkComplete > 0) && ((short)this.MSTask.PercentWorkComplete < 100); }
        }

        public bool IsExternalTask
        {
            get { return !string.IsNullOrEmpty(this.TaskNumber); }
        }

        public bool HasSubcases
        {
            get { return MSTask.OutlineChildren.Count > 0; }
        }

        public object OutlineParent
        {
            get { return MSTask.OutlineParent; }
        }

        public string FBCaseDescription
        {
            get
            {
                return string.Format("{0}{1}{2}",
                    this.TaskNumberFormatted,
                    string.IsNullOrEmpty(this.TaskNumberFormatted) ? string.Empty : " ",
                    this.Name);
            }
        }

        public bool IgnoreForComparison
        {
            get { return (bool)this.MSTask.Flag1; }
            set { this.MSTask.Flag1 = value; }
        }

        public MSTaskProxy(MSProjectProxy msProjectProxy, Microsoft.Office.Interop.MSProject.Task task)
        {
            if (task == null)
                throw new ArgumentNullException("task");

            this.MSProjectProxy = msProjectProxy;
            this.MSTask = task;
        }

        public MSTaskProxy(MSProjectProxy msProjectProxy, Microsoft.Office.Interop.MSProject.Task task, ExternalTask externalTask)
            : this(msProjectProxy, task)
        {
            if (externalTask == null)
                throw new ArgumentNullException("externalTask");

            this.MSTask.Manual = false;
            this.MSTask.Type = Microsoft.Office.Interop.MSProject.PjTaskFixedType.pjFixedWork;

            this.TaskNumber = externalTask.TaskNumber;
            this.Milestone = externalTask.Milestone;
            this.Priority = externalTask.Priority;
            this.Resource = externalTask.Resource;
            this.Estimate = externalTask.Estimate;
            this.Work = externalTask.RemainingWork;
            this.IgnoreForComparison = false;
        }

        public IList<TaskDifference> GetTaskDifferences(ExternalTask externalTask)
        {
            if (externalTask == null)
                throw new ArgumentNullException("externalTask");

            var taskDifferences = new List<TaskDifference>();

            if (this.Completed != externalTask.Completed)
            {
                taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.Completed, this.Completed.ToString(), externalTask.Completed.ToString()));
            }

            if (this.Name.Trim() != externalTask.Name.Trim())
            {
                taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.Name, this.Name, externalTask.Name));
            }

            if (this.Milestone != externalTask.Milestone)
            {
                taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.Milestone, this.Milestone, externalTask.Milestone));
            }

            if (this.Priority != externalTask.Priority)
            {
                taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.Priority, this.Priority.ToString(CultureInfo.InvariantCulture), externalTask.Priority.ToString(CultureInfo.InvariantCulture)));
            }

            if (!externalTask.Completed)
            {
                if (Math.Abs(this.Estimate - externalTask.Estimate) > 1)
                {
                    taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.Estimate, string.Format(CultureInfo.InvariantCulture, "{0:0.00}", this.Estimate / 60.0), string.Format(CultureInfo.InvariantCulture, "{0:0.00}", externalTask.Estimate / 60.0)));
                }

                if (Math.Abs(this.RemainingWork - externalTask.RemainingWork) > 1)
                {
                    taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.RemainingWork, string.Format(CultureInfo.InvariantCulture, "{0:0.00}", this.RemainingWork / 60.0), string.Format(CultureInfo.InvariantCulture, "{0:0.00}", externalTask.RemainingWork / 60.0)));
                }

                if (this.Resource != externalTask.Resource)
                {
                    taskDifferences.Add(new TaskDifference(this.Id, this.FBCaseDescription, this.TaskHyperlink, TaskDifferenceType.Resource, this.Resource, externalTask.Resource));
                }
            }

            return taskDifferences;
        }

        public void OutlineShowAllTasks()
        {
            this.MSTask.OutlineShowAllTasks();
        }

        public void OutlineHideSubTasks()
        {
            this.MSTask.OutlineHideSubTasks();
        }

    }
}
